#ifdef GL_FRAGMENT_PRECISION_HIGH
	precision highp float;
#else
	precision mediump float;
#endif

uniform lowp sampler2D ambientSampler;
uniform lowp sampler2D textureSampler;
uniform lowp sampler2D normalsSampler;

uniform vec3 lightDir;				// eg normalize(vec3(1,3,1))
uniform float specular_power;		// eg 75.0
uniform float mf;					// eg N = 1.6; mf = pow( ( N - 1.0 ) / ( N + 1.0 ), 2.0);
uniform mat4 uMVMatrix;

varying vec3 pos;
varying vec2 ambCoords;

void main()
{

	// compute normal vector (in world space)
	vec3 v = texture2D(normalsSampler, ambCoords).rgb - 0.5;
	vec3 pnorm = normalize(vec3(uMVMatrix * vec4(v, 0.0)));
	
	vec3 view		= normalize(pos);
	vec3 halfV	= normalize(lightDir - view);
	
	// consider doing these per vertex
	float ndotHalfV = max(dot(pnorm, halfV ), 0.0);
	
	// compute specular component
	float ks = pow(ndotHalfV, specular_power);
	
	// compute diffuse component
	float kd = max(dot(pnorm, lightDir), 0.0);
	
	// compute fresnel term
	float viewNormDot = dot(view, pnorm );
	float c	= min(viewNormDot, 0.0);
	float kf	= mf + (1.0 - mf) * pow( 1.0 + c, 5.0);
	
	// get the reflection color
	// procedurally what we do here is find the y component
	// of reflection vector and use it to find color
	float ry = view.y - 2.0 * viewNormDot * pnorm.y;
	float rl = fract(-ry);
	
	lowp float ka = texture2D(ambientSampler, ambCoords).r;
	lowp vec3 textureColor = texture2D(textureSampler, ambCoords).rgb;

	// accumulate ambient+diffuse, specular, and fresnel components;
	lowp vec3 cad	= (ka * 0.2 + 0.8 * ka * kd) * textureColor.rgb;
	lowp vec3 cs	= vec3(0.5 * ks);
	lowp vec3 cf	= vec3(kf * rl);
	
	gl_FragColor = vec4( cad + cs + cf, 1.0 );

}